//
//  ViewController.m
//  扫描二维码
//
//  Created by JS1-ZWN on 16/4/7.
//  Copyright © 2016年 JS1-ZWN. All rights reserved.
//

#import "NZScanViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "ZXingObjC.h"

#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
#define MarginLeft 50
#define ButtonWidth 35

@interface NZScanViewController () <AVCaptureMetadataOutputObjectsDelegate,UIAlertViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate>
{
    AVCaptureSession *session;// 输入输出的中间桥梁
}
@property (weak, nonatomic) UIImageView *scanArea;

@end

@implementation NZScanViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    //设置导航栏
    [self setUpNavigation];
    
    //扫描框
    [self scanFrame];
    
    //设置扫描线
    [self scanLine];
    
    //设置遮罩
    [self mask];
    
    //调整扫描区域 因为背景图的原因，四个角会被完全包在遮罩层下，这里让角突出一点点
    [self.view bringSubviewToFront:self.scanArea];
    CGRect originFrame = self.scanArea.frame;
    self.scanArea.frame = CGRectMake(originFrame.origin.x - 1.5, originFrame.origin.y - 1.5, originFrame.size.width + 3, originFrame.size.height + 3);
    
    //初始化扫描功能
    [self initScanWithRect:self.scanArea.frame];
    
}

#pragma mark - 设置视图
//导航栏
- (void)setUpNavigation
{
    //导航栏透明
    self.navigationController.navigationBar.translucent = YES;
    UIImage *clearBg = [[UIImage alloc] init];
    [self.navigationController.navigationBar setShadowImage:clearBg];
    [self.navigationController.navigationBar setBackgroundImage:clearBg forBarMetrics:UIBarMetricsDefault];
    //导航栏主题色
    self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
    
    //返回
    UIButton *back = [UIButton buttonWithType:UIButtonTypeCustom];
    [back setImage:[UIImage imageNamed:@"topbar_night_back"] forState:UIControlStateNormal];
    back.bounds = CGRectMake(0, 0, ButtonWidth, ButtonWidth);
    [back addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:back];
    
    //闪光灯
    UIButton *flash = [[UIButton alloc] init];
    flash.bounds = CGRectMake(0, 0, ButtonWidth, ButtonWidth);
    [flash setTitle:@"闪" forState:UIControlStateNormal];
    [flash setTintColor:[UIColor whiteColor]];
    [flash addTarget:self action:@selector(flash:) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *flashItem = [[UIBarButtonItem alloc] initWithCustomView:flash];
    
    //打开相册按钮
    UIImage *image = [UIImage imageNamed:@"album_image"];
    image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    UIButton *album = [UIButton buttonWithType:UIButtonTypeCustom];
    [album setImage:image forState:UIControlStateNormal];
    album.bounds = CGRectMake(0, 0, ButtonWidth, ButtonWidth);
    [album addTarget:self action:@selector(openAlbum) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *albumItem = [[UIBarButtonItem alloc] initWithCustomView:album];
    
    self.navigationItem.rightBarButtonItems = @[albumItem,flashItem];
}

//扫描框
- (void)scanFrame
{
    //设置扫描区域视图
    UIImageView *scanArea = [[UIImageView alloc] init];
    [self.view addSubview:scanArea];
    self.scanArea = scanArea;
    
    UIImage *frameImg = [UIImage imageNamed:@"qr_code_frame"];
    CGFloat cap = frameImg.size.width * 0.5;
    //设置扫描边框的图片的拉伸拉伸
    frameImg = [frameImg resizableImageWithCapInsets:UIEdgeInsetsMake(cap, cap, cap, cap )];
    self.scanArea.image = frameImg;
    
    CGFloat scanWidth = ScreenWidth - MarginLeft * 2;
    CGFloat x = (ScreenWidth - scanWidth) * 0.5;
    CGFloat y = (ScreenHeight - scanWidth) * 0.5;
    self.scanArea.frame = CGRectMake(x, y, scanWidth, scanWidth);
}

//扫描线
- (void)scanLine
{
    UIImageView *scanLineView = [[UIImageView alloc] init];
    scanLineView.frame = CGRectMake(4, 0, self.scanArea.frame.size.width - 6, 10);
    UIImage *scanLine = [UIImage imageNamed:@"qr_code_scan_line"];
    scanLineView.image = scanLine;
    [self.scanArea addSubview:scanLineView];
    
    CABasicAnimation *ani = [CABasicAnimation animation];
    ani.keyPath = @"transform.translation.y";
    ani.byValue = @(self.scanArea.frame.size.height - scanLineView.frame.size.height);
    ani.duration = 3.0;
    ani.repeatCount = MAXFLOAT;
    
    [scanLineView.layer addAnimation:ani forKey:nil];
    
}

//遮罩
- (void)mask
{
    //上遮罩
    [self maskWithFrame:CGRectMake(0, 0, ScreenWidth, self.scanArea.frame.origin.y)];
    //左遮罩
    [self maskWithFrame:CGRectMake(0, self.scanArea.frame.origin.y , MarginLeft , self.scanArea.frame.size.height)];
    //下遮罩
    [self maskWithFrame:CGRectMake(0,CGRectGetMaxY(self.scanArea.frame), ScreenWidth, ScreenHeight - CGRectGetMaxY(self.scanArea.frame))];
    //右遮罩
    [self maskWithFrame:CGRectMake(CGRectGetMaxX(self.scanArea.frame) ,self.scanArea.frame.origin.y, MarginLeft , self.scanArea.frame.size.height)];
}
- (void)maskWithFrame:(CGRect)frame
{
    //上遮罩
    UIView *mask = [[UIView alloc] init];
    mask.frame = frame;
    mask.backgroundColor = [UIColor blackColor];
    mask.alpha = 0.7;
    [self.view addSubview:mask];
}

#pragma mark - 初始化扫描功能
- (void)initScanWithRect:(CGRect)rect
{
    //获取摄像设备
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    //创建输入流
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    //创建输出流
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    
    //设置代理 在主线程里刷新
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    
    //初始化链接对象
    session = [[AVCaptureSession alloc] init];
    //高质量采集率
    [session setSessionPreset:AVCaptureSessionPresetHigh];
    
    [session addInput:input];
    [session addOutput:output];
    
    //设置扫码支持的编码格式
    output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];
    
    AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
    layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    layer.frame = self.view.layer.bounds;
    [self.view.layer insertSublayer:layer atIndex:0];
    
    //设置识别区域
    output.rectOfInterest = CGRectMake(rect.origin.y / ScreenHeight, rect.origin.x / ScreenWidth, rect.size.height / ScreenHeight, rect.size.width / ScreenWidth);
    
    //开始捕获
    [session startRunning];
}

#pragma mark - 导航栏上面按钮的方法
//返回
- (void)back
{
    
    //如果这个控制器是被Push出来的使用这个方法
//    [self.navigationController popViewControllerAnimated:YES];
    
    [self dismissViewControllerAnimated:YES completion:NULL];
}

//闪光灯
- (void)flash:(UIButton *)btn
{
    btn.selected = !btn.selected;
    
    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (captureDeviceClass != nil) {
        
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if ([device hasTorch] && [device hasFlash]) {
            
            [device lockForConfiguration:nil];
            if (btn.selected) {
                [device setTorchMode:AVCaptureTorchModeOn];
                [device setFlashMode:AVCaptureFlashModeOn];
            }else {
                [device setTorchMode:AVCaptureTorchModeOff];
                [device setFlashMode:AVCaptureFlashModeOff];
            }
            
            [device unlockForConfiguration];
        }
    }
    
}

//打开相册
- (void)openAlbum
{
    //创建图片选择控制器
    UIImagePickerController *pickVC = [[UIImagePickerController alloc] init];
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] ) {
        pickVC.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    }
    pickVC.delegate = self;
    pickVC.allowsEditing = YES;
    pickVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    
    [self presentViewController:pickVC animated:YES completion:NULL];
}

#pragma mark - AVCaptureMetadataOutputObjectsDelegate代理方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    if (metadataObjects.count <= 0) {
        return;
    }
    
    NSLog(@"%@",NSStringFromCGRect([session.outputs[0] rectOfInterest]));
    //获得扫描得出的字符串
    AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects objectAtIndex:0];
    [session stopRunning];
    
    [self showMessage:metadataObject.stringValue WithTitle:@"扫描成功"];
    
    
}



#pragma mark - 图片选择控制器代理方法
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    //获得所选择的图片
    UIImage *image = info[UIImagePickerControllerEditedImage];
    [self dismissViewControllerAnimated:YES completion:^{
        
        [self scanQRwithImage:image];
    }];
}

#pragma mark - 识别图片中的二维码
- (void)scanQRwithImage:(UIImage *)image
{
    //    CGImageRef imageRef = image.CGImage;
    
    ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:image.CGImage];
    ZXBinaryBitmap *bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]];
    
    ZXDecodeHints *hints = [ZXDecodeHints hints];
    
    ZXMultiFormatReader *reader = [ZXMultiFormatReader reader];
    
    NSError *error = nil;
    ZXResult  *result = [reader decode:bitmap hints:hints error:&error];
    
    
    if (result) {
        
        [self showMessage:result.text WithTitle:@"扫描成功"];
    }else {
        [self showMessage:@"图片内没有二维码" WithTitle:@"扫描失败"];
    }
}

//测试用
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    [session startRunning];
    
}

- (void)showMessage:(NSString *)message WithTitle:(NSString *)title
{
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles: nil];
    [alertView show];
}


@end
